package com.iotechn.unimall.biz.service.seckill;

import com.alibaba.fastjson.JSONObject;
import com.iotechn.unimall.core.exception.AppServiceException;
import com.iotechn.unimall.core.exception.ExceptionDefinition;
import com.iotechn.unimall.data.domain.SeckillSkuDO;
import com.iotechn.unimall.data.domain.SeckillSpuDO;
import com.iotechn.unimall.data.dto.order.OrderRequestSkuDTO;
import com.iotechn.unimall.data.mapper.SeckillSkuMapper;
import com.iotechn.unimall.data.mapper.SeckillSpuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Service
public class SeckillSpuBizService {
    @Autowired
    private SeckillSpuMapper seckillSpuMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //秒杀商品缓存前缀
    private final static String SECKILL_SPU_PREFIX="seck_spu_pre:";

    Lock lock = new ReentrantLock();

    public SeckillSpuDO selectByUpdateSeckillSpuDO(Long seckillSpuId, OrderRequestSkuDTO item)  throws Exception{
        lock.lock();
        SeckillSpuDO seckillSpuDO= new SeckillSpuDO();
        try {
            //查询缓存库存
            String seckillSpuDOJson = stringRedisTemplate.opsForValue().get(SECKILL_SPU_PREFIX+seckillSpuId);
            if(seckillSpuDOJson !=null && item.getSeckillSkuId() != null){
                seckillSpuDO= JSONObject.parseObject(seckillSpuDOJson, SeckillSpuDO.class);
            }
            if(seckillSpuDOJson ==null){
                seckillSpuDO = seckillSpuMapper.selectById(seckillSpuId);
                String value =  JSONObject.toJSON(seckillSpuDO).toString();
                stringRedisTemplate.opsForValue().set(SECKILL_SPU_PREFIX+item.getSeckillSkuId(),value,1, TimeUnit.DAYS);
            }
            //进行库存修改
            Float stockCount= seckillSpuDO.getStockCount()-item.getNum();
            if(stockCount < 0){
                throw new AppServiceException(ExceptionDefinition.ORDER_SYSTEM_BUSY);
            }
            Float seckillSpuSalessOld = seckillSpuDO.getSeckillSpuSales() == null ? 0 : seckillSpuDO.getSeckillSpuSales();
            seckillSpuDO.setSeckillSpuSales(seckillSpuSalessOld+item.getNum());
            seckillSpuDO.setStockCount(stockCount);
            String value =  JSONObject.toJSON(seckillSpuDO).toString();
            stringRedisTemplate.opsForValue().set(SECKILL_SPU_PREFIX+seckillSpuDO.getId(),value,1, TimeUnit.DAYS);
        } catch (Exception e) {
            throw new Exception();
        }finally {
            lock.unlock();
        }
        return seckillSpuDO;
    }
}